#pragma once

#include <iostream>
#include <cstdio>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>

#define PATH "."
#define NAME "fifo"

#define ERR_EXIT(m)         \
    do                      \
    {                       \
        perror(m);          \
        exit(EXIT_FAILURE); \
    } while (0)

class Fifo
{
public:
    Fifo(const std::string &path, const std::string &name)
        : _path(path), _name(name)
    {
        _allpath = _path + "/" + _name;
    }

    ~Fifo()
    {
    }

    void Creat()
    {
        int n = mkfifo(_allpath.c_str(),0666); 
        if(n == 0)
        {
            std::cout<< "创建成功" <<std::endl;
        }
        else if(n == -1)
        {
            ERR_EXIT("mkfifo fail");
        }
    }

    void OpenW()
    {
        int n = open(_allpath.c_str(),O_WRONLY);
        if(n == -1)
        {
            ERR_EXIT("openw fail");
        }
        else
        {
            _fd = n;
            std::cout<< "openw success" << std::endl;
        }
    }

    void OpenR()
    {
        int n = open(_allpath.c_str(),O_RDONLY);
        if(n == -1)
        {
            ERR_EXIT("openr fail");
        }
        else
        {
            _fd = n;
            std::cout<< "openr success" << std::endl;
        }
    }

    void Close()
    {
        close(_fd);
    }

    void Write()
    {
        std::string message;
        int cnt = 0;
        pid_t pid = getpid();
        while(true)
        {
            std::cout << "请输入：";
            std::getline(std::cin,message);
            message += "-进程" + std::to_string(pid) +"-" +std::to_string(cnt++);
            write(_fd,message.c_str(),message.size());
        }
    }

    void Read()
    {
        char buffer[1024];
        while(true)
        {
            int n = read(_fd,buffer,sizeof(buffer) - 1);
            if(n == -1)
            {
                ERR_EXIT("read fail");
            }
            else if(n == 0)
            {
                std::cout<< "client 退出" <<std::endl;
                break;
            }
            else
            {
                buffer[n] = 0;
                std::cout << "client say:" << buffer << std::endl;
            }
        }
    }

    void Clean()
    {
        int n =unlink(_allpath.c_str());
        if(n == -1)
        {
            ERR_EXIT("unlink fail");
        }
        else if(n == 0)
        {
            std::cout<< "unlink success" <<std::endl;
        }
    }

private:
    std::string _path;
    std::string _name;
    std::string _allpath;
    int _fd; 
};
